home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-29 | 8.5 KB | 265 lines | [TEXT/EMAC] |
- ;;;
- ;;; This file is part of a Macintosh port of GNU Emacs.
- ;;; Copyright (C) 1993 Marc Parmet. All rights reserved.
- ;;;
- ;;; Utilities for Apple event calls
- ;;;
-
- (defun ae-extract-args (key arglist)
- (cond
- ((null arglist)
- nil)
- ((eq (car (car arglist)) key)
- (cons (car (cdr (car arglist))) (ae-extract-args key (cdr arglist))))
- (t
- (ae-extract-args key (cdr arglist)))))
-
- (defun ae-generate-outs (n outs)
- (cond
- ((null outs)
- nil)
- (t
- (cons
- (list 'list ''setq (car outs) (list 'list ''nth n ''temp))
- (ae-generate-outs (1+ n) (cdr outs))))))
-
- (defun ae-create-interface (func arglist)
- (let ((ins (ae-extract-args 'in arglist))
- (outs (ae-extract-args 'out arglist)))
- (list 'defmacro
- func
- (mapcar (function (lambda (x) (car (cdr x)))) arglist)
- (append
- (list 'list ''let
- (list 'list
- (list 'list ''temp
- (append
- (list 'list
- (list 'quote
- (intern (concat (symbol-name func)
- "-internal")))) ins))))
- (ae-generate-outs 0 outs)
- (list (list 'list ''nthcdr (length outs) ''temp))))))
-
- (eval (ae-create-interface 'CreateObjSpecifier '((in desiredClass)
- (in theContainer)
- (in keyForm)
- (in keyData)
- (in disposeInputs)
- (out objSpecifier))))
-
- (eval (ae-create-interface 'unix-filename-to-FSSpec '((in filename)
- (out spec))))
-
- (defun make-init-string (base len)
- (ae-extract "string" base 0 len))
-
- (defun deref (address)
- (ae-extract typeLongInteger address 0))
-
- ;;;
- ;;; A macro we use in construction of Apple events.
- ;;; We should eventually rewrite this using signal.
- ;;;
-
- (defmacro catch-err (form &optional condition)
- (list 'let (list (list 'err form))
- (list 'if (or condition '(not (zerop err))) (list 'throw ''bailout 'err))))
-
- ;;;
- ;;; A convenient way to create Apple events to a specific target
- ;;;
-
- (defun ae-create-apple-event-internal (targetID eventClass eventID)
- (let* ((target (make-string sizeof-AEDesc 0))
- have-target
- (event (make-string sizeof-AppleEvent 0))
- have-event
- (actualSize (make-string 4 0))
- (resultType (make-string 4 0))
- (transactionID (make-string 4 0))
- (result
- (catch 'bailout
- (catch-err (AECreateDesc typeApplSignature targetID 4 target))
- (setq have-target t)
- (catch-err (AECreateAppleEvent eventClass eventID target
- kAutoGenerateReturnID
- kAnyTransactionID event))
- (setq have-event t)
- (catch-err (AEGetAttributePtr event keyReturnIDAttr typeLongInteger
- resultType transactionID 4 actualSize))
- noErr)))
- (if have-target (AEDisposeDesc target))
- (if (zerop result)
- (cons result (cons event (ae-extract typeLongInteger transactionID 0)))
- (cons result (cons nil nil)))))
-
- (defmacro ae-create-apple-event (targetID eventClass eventID event transactionID)
- (` (let ((temp (ae-create-apple-event-internal (, targetID)
- (, eventClass) (, eventID))))
- (setq (, event) (car (cdr temp)))
- (setq (, transactionID) (cdr (cdr temp)))
- (car temp))))
-
- (defvar ae-history nil "A list of Apple events sent from Emacs. This list is used to associate replies.")
-
- (defun AliasHandle-aliasSize (ah)
- (HLock ah)
- (unwind-protect
- (let ((s (make-init-string (deref ah) 6)))
- (ae-extract typeShortInteger s 4))
- (HUnlock ah)))
-
- (defun ae-have-required-parameters (event)
- (let* ((actualSize (make-string 4 0))
- (resultType (make-string 4 0))
- (data (make-string 0 0))
- (err (AEGetAttributePtr event keyMissedKeywordAttr typeWildCard
- returnedType data 0 actualSize)))
- (cond
- ((= err errAEDescNotFound)
- noErr)
- ((= err noErr)
- errAEEventNotHandled)
- (t
- err))))
-
- (defun short-time-string ()
- "Returns a string representing the time of day."
- (let* ((s (current-time-string))
- (blank-3 10)
- (blank-4 19))
- (substring s (1+ blank-3) blank-4)))
-
- (defun insert-reply (&rest s)
- (let ((errors-buffer (get-buffer-create "*replies*"))
- (original-window (selected-window)))
- (if (not (get-buffer-window errors-buffer))
- (let ((errors-window
- (if (eq (next-window) original-window)
- (split-window original-window
- (- (window-height (selected-window)) 8))
- (display-buffer errors-buffer))))
- (set-window-buffer errors-window errors-buffer)))
- (select-window (get-buffer-window errors-buffer))
- (set-buffer errors-buffer)
- (goto-char (point-max))
- (apply (function insert) s)
- (goto-char (point-max))
- (select-window original-window)))
-
- (defun do-ae-answer (event reply refCon)
- (let* ((actualSize (make-string 4 0))
- (resultType (make-string 4 0))
- (transactionID-string (make-string 4 0))
- (err (AEGetAttributePtr event keyReturnIDAttr typeLongInteger
- resultType transactionID-string 4 actualSize)))
- (if (not (zerop err))
- (insert-reply "Received a reply, but cannot determine original request\n")
- (let* ((transactionID-number (ae-extract typeLongInteger transactionID-string 0))
- (history (assoc transactionID-number ae-history)))
- (if (not history)
- (insert-reply "Received a reply with ID "
- (int-to-string transactionID-number)
- ", but cannot determine original request\n")
- (let ((handler (cdr (assoc 'handler (cdr history)))))
- (if handler
- (funcall handler event history)
- noErr)))))))
-
- ;;;
- ;;; A simple reply handler
- ;;;
-
- (defun announce-reply (history)
- (let ((description (cdr (assoc 'description (cdr history)))))
- (insert-reply "Reply at " (short-time-string)
- (if description (concat " to “" description "”") "")
- ":\n")))
-
- (defun do-simple-reply (event history)
- (announce-reply history)
- (let* ((error-number-data (make-string 4 0))
- (returnedType (make-string 4 0))
- (actualSize (make-string 4 0))
- (err (AEGetParamPtr event keyErrorNumber typeLongInteger returnedType
- error-number-data (length error-number-data) actualSize)))
- (cond
- ((zerop err)
- (let ((error-number (ae-extract typeLongInteger error-number-data 0)))
- (insert-reply " Error " (error-string error-number) "\n"))
- noErr)
- ((= err errAEDescNotFound)
- (insert-reply " No data was sent in reply.\n")
- noErr)
- (t
- (insert-reply " Could not read result, got error " (error-string err) ".\n")
- err))))
-
- (defun error-string (error-number)
- (concat (int-to-string error-number)
- (let ((s (lookup-error-string error-number)))
- (if s (concat ", “" s "”") ""))))
-
- (defun report-error-in-message-line (err)
- (if (not (zerop err))
- (let ((error-string (lookup-error-string err)))
- (message (concat "While sending Apple event, got error "
- (int-to-string err)
- (if error-string (concat ", “" error-string "”") ""))))))
-
- (defun launch-application (name)
- "Launch the application named APPLICATION in ~/etc."
- (let* (target
- event
- have-event
- (reply (make-string sizeof-AppleEvent 0))
- transactionID
- spec
- (alias-string (make-string 4 0))
- alias-handle
- alias-data
- (ae-list (make-string sizeof-AEDescList 0))
- have-ae-list
- (result
- (catch 'bailout
- (progn
- (catch-err (ae-create-apple-event "MACS" kAEFinderEvents kAEOpenSelection
- event transactionID))
- (setq have-event t)
-
- (catch-err (unix-filename-to-FSSpec "/bin" spec))
- (catch-err (NewAlias 0 spec alias-string))
- (setq alias-handle (ae-extract typeLongInteger alias-string 0))
- (HLock alias-handle)
- (setq alias-data (make-init-string (deref alias-handle)
- (AliasHandle-aliasSize alias-handle)))
- (DisposHandle alias-handle)
- (catch-err (AEPutParamPtr event keyDirectObject typeAlias
- alias-data (length alias-data)))
-
- (catch-err (unix-filename-to-FSSpec (concat "/bin/" name) spec))
- (catch-err (NewAliasMinimal spec alias-string))
- (setq alias-handle (ae-extract typeLongInteger alias-string 0))
- (HLock alias-handle)
- (setq alias-data (make-init-string (deref alias-handle)
- (AliasHandle-aliasSize alias-handle)))
- (DisposHandle alias-handle)
- (catch-err (AECreateList 0 0 0 ae-list))
- (setq have-ae-list t)
- (catch-err (AEPutPtr ae-list 0 typeAlias alias-data (length alias-data)))
- (catch-err (AEPutParamDesc event keySelection ae-list))
-
- (catch-err (AESend event reply (+ kAEQueueReply kAENeverInteract)
- kAENormalPriority kAEDefaultTimeout 0 0))
- (setq ae-history (cons (cons transactionID
- (list
- (cons 'description (concat "launch " name))))
- ae-history))
- noErr))))
- (if have-event (AEDisposeDesc event))
- (if have-ae-list (AEDisposeDesc ae-list))
- result))
-
- (AEInstallEventHandler kCoreEventClass kAEAnswer 'do-ae-answer 0 0)
-